﻿using IOP.SgrA;
using IOP.SgrA.SilkNet.Vulkan;
using Microsoft.Extensions.Logging;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Text;

namespace VkSample101
{
    public class MainMiddleware : IProductionLineMiddleware<PrimaryVulkanRenderGroup>
    {
        public void Invoke(PrimaryVulkanRenderGroup group, RenderingProductionLineDelegate<PrimaryVulkanRenderGroup> next)
        {
            try
            {
                var queue = group.WorkQueues[0].Queue;
                var cmdBuffer = group.PrimaryCommandBuffer;
                var semaphores = group.Semaphores;
                var pass = group.RenderPass;
                var face = group.Fences;
                var lDevice = group.LogicDevice;

                VulkanFrameBuffer framebuffer = group.RenderPass.GetFramebuffer(group.CurrentFrame);
                cmdBuffer.Reset();
                cmdBuffer.Begin();
                cmdBuffer.BeginRenderPass(pass, framebuffer, pass.BeginOption, SubpassContents.SecondaryCommandBuffers);
                group.SecondaryGroupRendering(pass, framebuffer);
                cmdBuffer.ExecuteCommands(group.GetUpdateSecondaryBuffers());
                cmdBuffer.EndRenderPass();
                cmdBuffer.End();

                var submitInfo = new SubmitOption
                {
                    WaitDstStageMask = new PipelineStageFlags[] { PipelineStageFlags.PipelineStageColorAttachmentOutputBit },
                    WaitSemaphores = new Semaphore[] { semaphores[0] },
                    Buffers = new CommandBuffer[] { cmdBuffer.RawHandle },
                    SignalSemaphores = new Semaphore[] { semaphores[1] }
                };
                lDevice.Submit(queue, face[0], submitInfo);
                Result r = Result.Timeout;
                do
                {
                    r = group.LogicDevice.WaitForFences(face, true, 100000000);
                } while (r == Result.Timeout);
                group.LogicDevice.ResetFences(face);
            }
            catch (Exception e)
            {
                group.Logger.LogError(e.Message + "\r\n" + e.StackTrace);
                group.Disable();
            }
        }
    }
}
